package org.example.journal_items.service.impl;

import org.example.journal_items.Repository.DiaryRepository;
import org.example.journal_items.UserDao.TodoDao;
import org.example.journal_items.Entity.Todo;
import org.example.journal_items.entityDTO.StatsDTO;
import org.example.journal_items.service.StatsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class StatsServiceImpl implements StatsService {

  @Autowired
  private DiaryRepository diaryRepository;

  @Autowired
  private TodoDao todoDao;

  @Override
  public StatsDTO getHomepageStats(Long userId) {
    try {
      // 1. 获取日记总数
      long totalDiaries = 0;
      try {
        totalDiaries = diaryRepository.countByUserId(userId);
      } catch (Exception e) {
        totalDiaries = 0;
      }

      // 2. 获取完成的待办事项数量
      long completedTodos = 0;
      try {
        List<Todo> allTodos = todoDao.findByUserId(userId);
        completedTodos = allTodos.stream()
            .filter(todo -> todo.getIsCompleted() != null && todo.getIsCompleted())
            .count();
      } catch (Exception e) {
        completedTodos = 0;
      }

      // 3. 获取收藏日记数量
      long favoriteDiaries = 0;
      try {
        favoriteDiaries = diaryRepository.countByUserIdAndIsFavorite(userId, true);
      } catch (Exception e) {
        favoriteDiaries = 0;
      }

      // 4. 计算连续记录天数
      long consecutiveDays = calculateConsecutiveDays(userId);

      // 5. 创建统计DTO
      StatsDTO stats = new StatsDTO();
      stats.setTotalDiaries(totalDiaries);
      stats.setCompletedTodos(completedTodos);
      stats.setFavoriteDiaries(favoriteDiaries);
      stats.setConsecutiveDays(consecutiveDays);

      return stats;

    } catch (Exception e) {
      throw new RuntimeException("获取统计数据失败: " + e.getMessage(), e);
    }
  }

  private long calculateConsecutiveDays(Long userId) {
    try {
      List<Date> dates = diaryRepository.findDistinctCreationDatesByUserId(userId);
      if (dates.isEmpty()) {
        return 0;
      }

      // 转换为LocalDate并去重排序，处理java.sql.Date类型
      List<LocalDate> localDates = dates.stream()
          .filter(d -> d != null) // 过滤掉null值
          .map(d -> {
            try {
              // 处理java.sql.Date类型
              if (d instanceof java.sql.Date) {
                return ((java.sql.Date) d).toLocalDate();
              } else {
                return d.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
              }
            } catch (Exception e) {
              return null;
            }
          })
          .filter(d -> d != null) // 过滤掉转换失败的日期
          .distinct()
          .sorted(Collections.reverseOrder())
          .collect(Collectors.toList());

      if (localDates.isEmpty()) {
        return 0;
      }

      LocalDate today = LocalDate.now();
      long consecutiveDays = 0;

      // 新规则：从最近的有记录日期开始向前累计，
      // 若今天无记录但昨天有记录，则应显示昨天为止的连续天数；
      // 若今天有记录，则包含今天继续累计。
      LocalDate start = localDates.contains(today) ? today
          : (localDates.contains(today.minusDays(1)) ? today.minusDays(1) : null);

      if (start == null) {
        return 0; // 今天和昨天都没有记录，连续为0
      }

      consecutiveDays = 1; // 从起始日算起
      LocalDate check = start.minusDays(1);
      while (localDates.contains(check)) {
        consecutiveDays++;
        check = check.minusDays(1);
      }

      return consecutiveDays;

    } catch (Exception e) {
      return 0;
    }
  }
}